package org.dreamfly.core.remote;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.dreamfly.core.remote.exception.ServiceException;
import org.dreamfly.core.remote.generator.ServiceIdProvider;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.beans.factory.FactoryBean;

import java.lang.reflect.Method;

/**
 * Created by IntelliJ IDEA.
 * User: Gin
 * Date: 2010-11-27
 * Time: 3:25:38
 * To change this template use File | Settings | File Templates.
 */
public class ServiceProxyFactory implements FactoryBean {

    /** 服务中心 */
    private ServiceRepository serviceRepository;

    /** 服务ID提供者 */
    private ServiceIdProvider serviceIdProvider;

    /** 服务接口 */
    private Class             serviceInterface;

    /*
     * @see org.springframework.beans.factory.FactoryBean#getObject()
     */
    public Object getObject() throws Exception {
        return ProxyFactory.getProxy(getObjectType(), new ServiceProxyInterceptor());
//        return serviceRepository.getService(serviceInterface, serviceIdProvider.getCurrentServiceId());
    }

    /*
     * @see org.springframework.beans.factory.FactoryBean#getObjectType()
     */
    public Class getObjectType() {
        return serviceInterface;
    }

    /*
     * @see org.springframework.beans.factory.FactoryBean#isSingleton()
     */
    public boolean isSingleton() {
        return true;
    }

    /*
     * 远程服务代理拦截器。
     */
    private class ServiceProxyInterceptor implements MethodInterceptor {

        /*
         * @see org.aopalliance.intercept.MethodInterceptor#invoke(org.aopalliance.intercept.MethodInvocation)
         */
        public Object invoke(MethodInvocation invocation) throws Throwable {

            Method method = invocation.getMethod();
            Object[] args = invocation.getArguments();
            Object client = getClient();
            return method.invoke(client, args);
        }

        private Object getClient() {
            try {
                return serviceRepository.getService(serviceInterface, serviceIdProvider.getCurrentServiceId());
            } catch (ServiceException e) {
                //TODO
                e.printStackTrace();
                return null;
            }
        }

    }

    // ---- 容器自动注入 ----

    /**
     * @param serviceRepository
     *            the serviceRepository to set
     */
    public void setServiceRepository(ServiceRepository serviceRepository) {
        this.serviceRepository = serviceRepository;
    }

    /**
     * @param serviceInterface
     *            the serviceInterface to set
     */
    public void setServiceInterface(Class serviceInterface) {
        this.serviceInterface = serviceInterface;
    }

    /**
     * @param serviceIdProvider
     *            the serviceIdProvider to set
     */
    public void setServiceIdProvider(ServiceIdProvider serviceIdProvider) {
        this.serviceIdProvider = serviceIdProvider;
    }
}

